Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce RoundingIncrement to FixedDecimal #4219

Merged
merged 3 commits into from
Oct 31, 2023

Conversation

jedel1043
Copy link
Contributor

@jedel1043 jedel1043 commented Oct 25, 2023

This PR implements an MVP of the RoundingIncrement API for FixedDecimal, which should allow rounding to increments that are divisors of 10 and 100. It also implements FixedDecimal::trunc_to_increment to show the usage of the API.

I plan to implement the remaining methods, but I wanted to create an MVP first to discuss if this would be the desired API.

Mostly based from #3929 (comment)

@jedel1043 jedel1043 requested a review from sffc as a code owner October 25, 2023 02:38
@jedel1043 jedel1043 force-pushed the rounding-increments branch 2 times, most recently from 6965970 to e96d4f2 Compare October 25, 2023 02:39
@jedel1043
Copy link
Contributor Author

jedel1043 commented Oct 25, 2023

Will implement the FFI glue code until the API is accepted, but everything else should be fine.

utils/fixed_decimal/src/decimal.rs Outdated Show resolved Hide resolved
utils/fixed_decimal/src/decimal.rs Outdated Show resolved Hide resolved
utils/fixed_decimal/src/decimal.rs Outdated Show resolved Hide resolved
utils/fixed_decimal/src/decimal.rs Outdated Show resolved Hide resolved
@jedel1043 jedel1043 changed the title Introduce RoundingIncrement to FixedDecimal Introduce RoundingCoarseness to FixedDecimal Oct 26, 2023
/// dec.trunc_coarse(-2, RoundingCoarseness::MultiplesOf2);
/// assert_eq!("9.98", dec.to_string());
/// ```
pub fn trunc_coarse(&mut self, position: i16, coarseness: RoundingCoarseness) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

naming: using "truncation" and "rounding" in the same API is confusing. This API never rounds, so RoundingCoarseness should probably be TruncationCoarseness, or some neutral term.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though, ECMA402 considers truncation as a "roundingMode"...
The obvious problem would be that TruncationCoarseness has the same problem when used in expand_coarse, since the API never truncates, and I can't find another term to encompass all operations.

Maybe we can just leave it as Coarseness?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess truncation is a special case of rounding. We can bikeshed this later.

robertbastian
robertbastian previously approved these changes Oct 26, 2023
Copy link
Member

@robertbastian robertbastian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm from me, would also like @sffc to take a look

@sffc sffc added discuss-priority Discuss at the next ICU4X meeting and removed discuss-priority Discuss at the next ICU4X meeting labels Oct 26, 2023
@jedel1043
Copy link
Contributor Author

Renaming to RoundingIncrement per #3929 (comment)

@jedel1043 jedel1043 changed the title Introduce RoundingCoarseness to FixedDecimal Introduce RoundingIncrement to FixedDecimal Oct 26, 2023
sffc
sffc previously approved these changes Oct 31, 2023
Copy link
Member

@sffc sffc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I finally took the time to review the algorithm in detail. Nice work!

}
RoundingIncrement::MultiplesOf2 => {
let Some(last_digit) = self.digits.last_mut() else {
// Unreachable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: use debug_assert!(false, "message") for unreachable code.


// Equivalent to (n / 2) * 2, which truncates to the previous
// multiple of two
*last_digit &= 0xFE;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Praise: this is a nice way to truncate to multiple of 2

Comment on lines +1148 to +1149
// Extend with zeroes to have the correct trailing digits.
self.digits.resize(digits_to_retain as usize, 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: what does this do? You already truncated self.digits to length digits_to_retain up above.

Copy link
Contributor Author

@jedel1043 jedel1043 Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for cases such as "0.60", which is represented as digits = [6], magnitude = -1.

Since we need digits = [6, 0] instead to modify to the next increment of 25, we extend to the exact digits of digits_to_retain so that we can modify the last, nonexistent zero.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, okay. "0.3" should truncate down to "0.25" which requires adding an extra digit, and this digit is reflected in digits_to_retain.

@sffc sffc merged commit 189b5be into unicode-org:main Oct 31, 2023
28 checks passed
@jedel1043 jedel1043 deleted the rounding-increments branch October 31, 2023 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants